﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;

using FrameDisplay.Services;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;

namespace FrameDisplayServer.Services
{

    public class FrameDisplayService : IFrameDisplayService
    {
        private void CheckAccessCode(string accessCode)
        {
            if (accessCode != AppCentral.SettingsManager.AccessCode)
            {
                throw new Exception("Access denied.");
            }
        }


        public Stream About()
        {
            WebOperationContext.Current.OutgoingResponse.ContentType = "text/html; charset=utf-8";

            MemoryStream memStream = new MemoryStream(
                Encoding.UTF8.GetBytes(
                "<html><body>"
                + "<b>FrameDisplayService</b>"
                + "</body></html>"
                ));

            return memStream;
        }

        public int Version()
        {
            // Return API revision.
            return 1;
        }

        public void HideFrame(string accessCode)
        {
            if (!AppCentral.IsInitialized)
            {
                throw new Exception("Not initialized.");
            }

            this.CheckAccessCode(accessCode);

            AppCentral.BrowserManager.HideFrame();
        }

        public void ShowUrl(string accessCode, string url)
        {
            if (!AppCentral.IsInitialized)
            {
                throw new Exception("Not initialized.");
            }

            this.CheckAccessCode(accessCode);

            AppCentral.BrowserManager.NavigateAndShow(url);
        }

        public void ShowYouTube(string accessCode, string videoID)
        {
            if (!AppCentral.IsInitialized)
            {
                throw new Exception("Not initialized.");
            }

            this.CheckAccessCode(accessCode);

            // NOTE: 
            //  #t=? is the start time in seconds
            //  &hd=1 is for high definition

            // TODO: Add support for play, stop, pause on the youtube screen.

            string url = String.Format(
                "http://www.youtube.com/watch_popup?v={0}&hd=1&pop_ads=NoAdSlots#t=0",
                videoID);
            AppCentral.BrowserManager.NavigateAndShow(url);
        }


        public void ShowImageFile(Stream image, string accessCode)
        {
            if (!AppCentral.IsInitialized)
            {
                throw new Exception("Not initialized.");
            }

            this.CheckAccessCode(accessCode);

            Image imageObject = Image.FromStream(image);
            AppCentral.BrowserManager.ShowImage(imageObject);
        }


        public Stream GetImageForCursorRegion(string accessCode, int width, int height)
        {
            if (!AppCentral.IsInitialized)
            {
                throw new Exception("Not initialized.");
            }
     
            this.CheckAccessCode(accessCode);

            if (width > 1000)            
                width = 1000;
            
            if (height > 1000)
                height = 1000;           

            MemoryStream imageStream = new MemoryStream();
            Image capturedImage = SharpScraps.Win32.ScreenCapture.CaptureCursorRegion(width, height);
            capturedImage.Save(imageStream, ImageFormat.Png);

            WebOperationContext.Current.OutgoingResponse.ContentType = "image/png";

            imageStream.Position = 0;
            return imageStream;
        }


        public void MousePress(string accessCode, string button, string action)
        {
            if (!AppCentral.IsInitialized)
            {
                throw new Exception("Not initialized.");
            }

            this.CheckAccessCode(accessCode);

            MouseButtons mouseButton;
            if (button == "Left")
                mouseButton = MouseButtons.Left;
            else if (button == "Right")
                mouseButton = MouseButtons.Right;
            else if (button == "Middle")
                mouseButton = MouseButtons.Middle;
            else
                throw new Exception("Invalid mouse button.");

            switch (action)
            {
                case "Down":
                    SharpScraps.Win32.Input.InputSender.MouseDown(mouseButton); 
                    break;

                case "Up":
                    SharpScraps.Win32.Input.InputSender.MouseUp(mouseButton);
                    break;

                case "Click":
                    SharpScraps.Win32.Input.InputSender.MouseDown(mouseButton);
                    SharpScraps.Win32.Input.InputSender.MouseUp(mouseButton);
                    break;
            }
        }


        public void MouseMove(string accessCode, int deltaX, int deltaY, bool absolute)
        {
            if (!AppCentral.IsInitialized)
            {
                throw new Exception("Not initialized.");
            }

            this.CheckAccessCode(accessCode);

            if (!absolute)
            {
                SharpScraps.Win32.Input.InputSender.MoveMouse(deltaX, deltaY);
            }
            else
            {
                Point pos = Cursor.Position;
                Cursor.Position = new Point(pos.X + deltaX, pos.Y + deltaY);
            }
        }

        public void SendKeys(string accessCode, string keys)
        {
            if (!AppCentral.IsInitialized)
            {
                throw new Exception("Not initialized.");
            }

            this.CheckAccessCode(accessCode);

            AppCentral.MainForm.BeginInvoke(
                new Action(delegate { System.Windows.Forms.SendKeys.Send(keys); }));
            
        }
    }
}
